﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Xml.Linq;

namespace VisualRibbonEditor
{
	/// <summary>
	/// Represents a group of controls on a ribbon
	/// </summary>
	public partial class RibbonGroup : UserControl
	{
		public XElement SourceElement { get; set; }

		public RibbonGroup(XElement groupElement)
		{
			InitializeComponent();

			SourceElement = groupElement;

			SetLabel();

			AddSections();
		}

		private StackPanel currentSmallButtonStack = null;

		private bool _isSelected = false;
		public bool IsSelected
		{
			get { return _isSelected; }
			set
			{
				_isSelected = value;
				if (_isSelected)
				{
					GroupBorder.BorderBrush = new SolidColorBrush(Colors.Blue);
				}
				else
				{
					GroupBorder.BorderBrush = new SolidColorBrush(Colors.Transparent);
				}
			}
		}

		private Dictionary<string, GroupSection> _sectionPanels = new Dictionary<string, GroupSection>();

		public void AddSections()
		{
			string templateId = SourceElement.AttributeValue("Template");
			
			//find the maxsize used for this group
			XElement maxSize = SourceElement.Ancestors("Tab").First()
				.Element("Scaling")
				.Elements("MaxSize").Where(x => x.AttributeValue("GroupId") == SourceElement.AttributeValue("Id")).FirstOrDefault();
			if (maxSize == null) return; // v2013: Modern Client buttons do not have correspoding MaxSize element in Scaling. Skipping
			string layoutTitle = maxSize.AttributeValue("Size");

			//find the groupTemplate
			XElement root = SourceElement.Ancestors().Last();
			XElement groupTemplate = root.Descendants("GroupTemplate").Where(x => x.AttributeValue("Id") == templateId).FirstOrDefault();
			if (groupTemplate != null)
			{
				XElement layout = groupTemplate.Elements("Layout").Where(x => x.AttributeValue("Title") == layoutTitle).FirstOrDefault();
				if (layout != null)
				{
					//add a section for the non-overflowsection controls
					if (layout.Descendants("Section").Count() > 0)
					{
						GroupSection section = new GroupSection(null);
						_sectionPanels["__ControlRefSection"] = section;
						ButtonsStackPanel.Children.Add(section);
					}
					
					//iterate through each templateAlias in the order they appear in the template layout
					foreach (XElement overflowSection in layout.Descendants("OverflowSection"))
					{
						string templateAlias = overflowSection.AttributeValue("TemplateAlias");

						GroupSection section = new GroupSection(overflowSection);
						_sectionPanels[templateAlias] = section;
						ButtonsStackPanel.Children.Add(section);
					}
				}
			}
		}

		public bool ShowTemplateAliasPreview
		{
			set
			{
				foreach (GroupSection section in _sectionPanels.Values)
				{
					section.ShowTemplateAlias = value;
				}
			}
		}


		private GroupSection _currentSection = null;
		 
		public void AddRibbonButton(RibbonButton button)
		{
			//dont show hidden buttons.
			if (Hider.IsControlHidden(button.SourceElement.AttributeValue("Id")))
			{
				return;
			}

			string templateAlias = button.SourceElement.AttributeValue("TemplateAlias");
			GroupSection section;
			if (_sectionPanels.ContainsKey(templateAlias))
			{
				section = _sectionPanels[templateAlias];
			}
			else
			{
				section = _sectionPanels["__ControlRefSection"];
			}
			if (section != _currentSection)
			{
				_currentSection = section;
				currentSmallButtonStack = null; //switching sections means starting over on a new 3-row stack.
			}

			if (button.Size == ButtonSize.Small)
			{
				//need to create a new vertical stack of small buttons
				if (currentSmallButtonStack == null)
				{
					currentSmallButtonStack = new StackPanel();
					//ButtonsStackPanel.Children.Add(currentSmallButtonStack);
					section.Stack.Children.Add(currentSmallButtonStack);
				}

				//add the button to the small vertical stack
				currentSmallButtonStack.Children.Add(button);

				//if the stack has 3 small button in it, then we are finished with it. 
				//(and should start a new stack if theres more small buttons)
				if (currentSmallButtonStack.Children.Count >= 3)
				{
					currentSmallButtonStack = null;
				}
			}
			else //its a large button
			{
				//add the large button to the groups main stackpanel
				//ButtonsStackPanel.Children.Add(button);
				section.Stack.Children.Add(button);
				
				//this will cause any small buttons added after this one to start a new vertical stackpanel
				currentSmallButtonStack = null;
			}

		}

		/// <summary>
		/// Sets the label of the group
		/// </summary>
		private void SetLabel()
		{
			//attempt to find the loclabel for this group
			XAttribute LabelText = SourceElement.Attribute("Title");
			if (LabelText != null)
			{
				if (LabelText.Value.StartsWith("$LocLabels:"))
				{
					string id = LabelText.Value.Replace("$LocLabels:", "");
					string label = Helpers.GetLocLabelTextById(id, "1033");
					if (label != null)
					{
						this.GroupNameLabel.Text = label;
						return;
					}
				}
			}

			//if no label can be found just use the id.
			string groupId = SourceElement.Attribute("Id").Value;
			this.GroupNameLabel.Text = Helpers.AddSpaces(groupId.Substring(groupId.LastIndexOf(".") + 1));
		}

		private void GroupNameLabel_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
		{
			if (Click != null)
			{
				Click(this, new RoutedEventArgs());
			}
		}

		public event RoutedEventHandler Click;

	}
}
